/*
 * @Descripttion: GGB
 * @version: 1.0
 * @Author: GGB
 * @Date: 2022-01-16 14:33:21
 * @LastEditors: GGB
 * @LastEditTime: 2022-02-02 08:05:50
 */
// 库


const { app, ipcMain, Menu, dialog } = require('electron')
const isDev = require('electron-is-dev')
const { autoUpdater}=require('electron-updater')


process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
const menuTemplate = require('./src/menuTemplate')
const { join } = require('path')
const QiniuManager = require("./src/utils/QiniuManager");

const Store = require('electron-store')
const settingsStore = new Store({ name: 'Settings' })
const fileStore = new Store({ name: 'Files Data' })

// const { v4 } = require('uuid')
const objToArr = (obj) => Object.keys(obj).map(key=>obj[key])


const AppWindow = require('./src/AppWindow')
let mainWindow, settingsWindow;
// 创建主窗口
function createWindow() {
  const mainWindowConfig = {
    width: 1200,
    height: 600,
    webPreferences: {
      nodeIntegration: true, // 是否集成 Nodejs 
      contextIsolation: false,
      enableRemoteModule: true,
      webSecurity: false
    }
  }
  const urlLocation = isDev ? 'http://localhost:3000' : `file://${join(__dirname, './index.html')}`
  console.log('urlLocation',urlLocation)
  mainWindow = new AppWindow(mainWindowConfig, urlLocation)
  require('@electron/remote/main').initialize()
  require('@electron/remote/main').enable(mainWindow.webContents)
  isDev && mainWindow.webContents.openDevTools()
  mainWindow.on('closed', () => {
    mainWindow = null
  })
}
// 打开设置窗口
function createSettingsWindow() {
  if (settingsWindow) return
  const settingsWindowConfig = {
    width: 800,
    height: 600,
    parent: mainWindow,
    webPreferences: {
      nodeIntegration: true, // 是否集成 Nodejs 
      contextIsolation: false,
      enableRemoteModule: true,
      webSecurity: false
    }
  }
  const settingsFileLocation = `file://${join(__dirname, './settings/settings.html')}`
  settingsWindow = new AppWindow(settingsWindowConfig, settingsFileLocation)
  settingsWindow.removeMenu()
  require('@electron/remote/main').enable(settingsWindow.webContents)
  isDev && settingsWindow.webContents.openDevTools()
  settingsWindow.on('closed', () => {
    settingsWindow = null
  })
}

// 创建文件管理实例
function createManager() {
  const accessKey = settingsStore.get('accessKey');
  const secretKey = settingsStore.get('secretKey');
  const bucket = settingsStore.get('bucketName');
  return new QiniuManager(accessKey, secretKey, bucket)
}

// 文件同步
function asyncFile(event, data) {
  const manager = createManager()
  let { key, path } = data
  manager.uploadFile(key, path).then(data => {
    console.log('上传成功', data)
    mainWindow.webContents.send('active-file-uploaded')
  }).catch((err) => {
    console.log(err)
    dialog.showErrorBox('同步失败', '请检查七牛云参数是否正确')
  })
}

// 更新菜单配置

function updateConfigMenu(menu) {
  let qiniuMenu = process.platform === 'darwin' ? menu.items[3] : menu.items[2]
  const switchItems = (toggle) => {
    [1, 2, 3].forEach(number => {
      qiniuMenu.submenu.items[number].enabled = toggle
    })
  }
  const qiniuIsConfiged = ['accessKey', 'secretKey', 'bucketName'].every(key => !!settingsStore.get(key))
  if (qiniuIsConfiged) {
    switchItems(true)
  } else {
    switchItems(false)

  }
}


// 同步线上文件到本地
function asyncLocalFile(event, data) {
  const filesObj = fileStore.get('files')
  const manager = createManager()
  const { key, path, id } = data
  console.log('asyncLocalFile', data)
  manager.getStat(key)
    .then(res => {
      const serverUpdateTime = Math.round(res.putTime / 10000)
      const localUpdateTime = filesObj[id].updateAt
      if (serverUpdateTime > localUpdateTime || !localUpdateTime) {
        manager.downloadFile(key, path).then(() => {
          mainWindow.webContents.send('file-downloaded', { status: 'download-success', id })
        }).catch(err => {
          console.log(err)
        })
      } else {
        mainWindow.webContents.send('file-downloaded', { status: 'no-new-file', id })
      }
    })
    .catch(err => {
      if (err.statusCode === 612) {
        mainWindow.webContents.send('file-downloaded', { status: 'no-file', id })
      }
    })
}
//  同步本地所有文件到线上
function asyncAllFile(event, data) {
  mainWindow.webContents.send('loading-status', true)
  //  构造一个 promise数组 进行处理上传
  const manager = createManager()
  const filesObj = fileStore.get('files') || {}
  const uploadPromiseArr = Object.keys(filesObj).map(key => {
    const file = filesObj[key]
    return manager.uploadFile(`${file.title}.md`, file.path)
  })
  Promise.all(uploadPromiseArr).then(result => {
    console.log(result)
    dialog.showMessageBox({
      type: 'info',
      title: `成功上传了${result.length}个文件`,
      message: `成功上传了${result.length}个文件`
    })
    mainWindow.webContents.send('files-uploaded')
  }).catch(() => {
    dialog.showErrorBox('上传失败', '请检查七牛云参数是否正确')
  }).finally(() => {
    mainWindow.webContents.send('loading-status', false)
  })
}

/**
 *  重命名云端文件
 * @param {*} event 
 * @param {*} data 
 */
function renameFile(event, data) {
  const { key, targetKey } = data
  const manager = createManager()
  manager.renameFile(key, targetKey).then(() => {
    console.log(res)
  }).catch(err => {
    dialog.showErrorBox('云端文件重命名失败', '请检查七牛云参数是否正确')
  })
}
/**
 *  重命名云端文件
 * @param {*} event 
 * @param {*} data 
 */
function deleteFile(event, data) {
  const { key} = data
  const manager = createManager()
  manager.deleteFile(key).then(() => {
    console.log(res)
  }).catch(err => {
    dialog.showErrorBox('云端文件删除失败', '请检查七牛云参数是否正确')
  })
}
/**
 * 同步云端数据
 */
// function asyncCloudFile() { 
//   const manager = createManager()
//   const files = fileStore.get('files')
//    // 文件数组
//   const filesArr = objToArr(files)
//   const currentArr=[]
//   // step 1 获取文件列表
//   manager.getFileList().then(res => { 
//     const { items}=res
//     const downloadPromiseArr = items.filter(item => { 
//       // step 2 和本地文件对比判断是否要下载，应该包括比本地新的，本地没有的
//     // 怎么样做快速的对比，是一个难点，因为从七牛云取回来的数据没有我们系统中的id
//       const currentFile = filesArr.find(file => `${file.title}.md` === item.key)
//       if (!currentFile) return item
//       const serverUpdateTime = Math.round(item.putTime / 10000)
//       const localUpdateTime = currentFile.updateAt 
//       if (serverUpdateTime > localUpdateTime) return {...item,id:currentFile.id,path:currentFile.path}
//     }).map(item => { 
//       // step 3使用文件列表生成下载文件的promise数组
//       const savedLocation = settingsStore.get('savedFileLocation') || app.getPath('documents')
//       // 处理文件路径
//       const path = item.path ? item.path : `${savedLocation}/${item.key}`
//       item.path = path
//       item.title=item.title||item.key.replace('.md','')
//       // 数据处理
//       currentArr.push(item)
//       return manager.downloadFile(item.key,path)
//     })
//      // step 3使用文件列表生成下载文件的promise数组
//     // return Promise.all(downloadPromiseArr)
//     Promise.all(downloadPromiseArr)
//   }).then(() => { 

//      // step 4 显示 messageBox
//     dialog.showMessageBox({
//       type:'info',
//       title:'同步完成'
//     })
//     // todo 目前这一部分未完成
//     return 
//     // step 5 生成新的 FilesObject
//     //  目的是生成一个新的key 为 id ,value 为文件详情的object
//     const finalFilesObj = arr.reduce((newFilesObj, qiniuFile) => {
//       const currentFile = filesArr.find(file => `${file.title}.md` === qiniuFile.key)
//       if (currentFile) {
//         const existedKey=currentFile.id
//         const updatedItem = {
//           ...currentFilesObj[existedKey],
//           isSynced: true,
//           updateAt:new Date().getTime()
//         }
//         return {
//           ...newFilesObj,
//           [existedKey]:updatedItem
//         }
//       } else { 
//         const newId = new v4()
//         const newItem = {
//           id: newId,
//           isSynced: true,
//           // TODO 这里差一个数据内容的赋值
//           title:qiniuFile.title,
//           updateAt:new Date().getTime()
//         }
//         return {
//           ...newFilesObj,
//           [newId]: newItem,
          
//         }
//       }
//     }, { ...currentFilesObj })
//     // 更新界面数据
//   }).catch(err => { 
//     dialog.showErrorBox('云端文件下载失败', '请检查七牛云参数是否正确')
//   })
// }
// 自动更新
function autoUpdate() { 
  if (isDev) { 
    autoUpdater.updateConfigPath=join(__dirname,'dev-app-update.yml')
  }
  autoUpdater.autoDownload = false
  // autoUpdater.checkForUpdatesAndNotify()
  autoUpdater.checkForUpdates()
  autoUpdater.on('error', (error) => { 
    dialog.showErrorBox('Error',error===null?'unknown':(error.status))
  })
  autoUpdater.on('checking-for-update', () => { 
    console.log('Checking for update ...')
  })
  autoUpdater.on('download-progress', (progressObj) => { 
    let log_message = "Download speed:" + progressObj.bytesPerSecond
    log_message = log_message + '- Downloaded ' + progressObj.percent + '%'
    console.log(log_message)
  })
  autoUpdater.on('update-available', () => { 
    dialog.showMessageBox({
      type: 'info',
      title: '应用有新的版本',
      message: '发现新版本，是否现在更新？',
      buttons:['是','否']
    }, (buttonIndex) => { 
      if (buttonIndex === 0) { 
        autoUpdater.downloadUpdate()
      }
    })
  })

  autoUpdater.on('update-downloaded', () => { 
    dialog.showMessageBox({
      title: '安装更新',
      message:'更新下载完毕，应用将重启并进行安装'
    }, () => { 
      setImmediate(() =>autoUpdater.quitAndInstall())
    })
  })

  autoUpdater.on('update-not-available', () => { 
    dialog.showMessageBox({
      title: '没有新版本',
      message: '没有新版本',
    })
  })
}

app.whenReady().then(() => {
  // 自动更新
  autoUpdate()
  
  // 创建窗口
  createWindow()
  // setMenu
  let menu = Menu.buildFromTemplate(menuTemplate)
  Menu.setApplicationMenu(menu)
  // hook up main events
  ipcMain.on('open-settings-window', createSettingsWindow)
  // 更新菜单配置
  ipcMain.on('config-is-saved', () => {
    // watch out menu items index of max and window
    updateConfigMenu(menu)
  })
  // // 文件同步
  ipcMain.on('upload-file', asyncFile)

  // // 同步文件到本地
  ipcMain.on('download-file', asyncLocalFile)

  // // 同步全部文件到云端
  ipcMain.on('upload-all-to-qiniu', asyncAllFile)
  // 重命名云端文件
  ipcMain.on('rename-file', renameFile)
  // 重命名云端文件
  ipcMain.on('delete-file', deleteFile)
  // 重命名云端文件
  // ipcMain.on('download-all-to-local', asyncCloudFile)
})